home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / byte0887.arc / LANE.ARC / OPS8085.ARI < prev    next >
Text File  |  1987-05-05  |  28KB  |  901 lines

  1. % Subject: OPS8085.ARI - from A. Lane: "Simulating an 8085 with Prolog"
  2.  
  3. comp_regs(Regname) :-
  4.         retract(state(R,PC,SP,_)),
  5.         reg(Regname,Place),
  6.         arg(Place,R,Reg),
  7.         X is A - Reg,
  8.         adjust_flags(A,X,_,Flags),
  9.         asserta(state(R,PC,SP,Flags)).
  10.  
  11. acc_math_with_carry(Op,Regname) :-
  12.         retract(state(R,PC,SP,flags(_,_,_,CY,_))), % get what we need
  13.         arg(1,R,A),                                % extract A from R
  14.         reg(Regname,Place),    % Place is location of Regname in R
  15.         arg(Place,R,Reg),      % extract register value
  16.         T1 =.. [Op,Reg,CY],    % set up additions/subtractions
  17.         T2 =.. [Op,A,T1],
  18.         X is T2,               % evaluate
  19.         adjust_flags(A,X,Y,Flags),  % adjust for flags
  20.         argrep(R,1,Y,NewR),       % replace register value in R
  21.         asserta(state(NewR,PC,SP,Flags)).
  22.  
  23. acc_math(Op,Regname) :-
  24.         retract(state(R,PC,SP,_)),
  25.         arg(1,R,A),
  26.         reg(Regname,Place), arg(Place,R,Reg),
  27.         T1 =.. [Op,A,Reg],
  28.         X is T1,
  29.         adjust_flags(A,X,Y,Flags),
  30.         argrep(R,1,Y,NewR),
  31.         asserta(state(NewR,PC,SP,Flags)).
  32.  
  33. reg_math(Op,Regname) :-
  34.         retract(state(R,PC,SP,flags(_,_,_,CY,_))), arg(1,R,A),
  35.         reg(Regname,Place),    % Place is location of Regname in R
  36.         arg(Place,R,Reg),      % extract register value
  37.         T1 =.. [Op,Reg,TemReg],% take advantage of Arity inc() and dec()
  38.         call(T1),
  39.         adjust_flags(A,TemReg,NewReg,flags1(Z,S,P,_,AC)),
  40.         argrep(R,1,NewReg,NewR),       % replace register value in R
  41.         asserta(state(NewR,PC,SP,flags(Z,S,P,CY,AC))).
  42.  
  43. not_implemented.    % some things are not worth doing.
  44.  
  45. undefined.
  46.  
  47. move(mem, mem).
  48.  
  49. move(mem,D) :-
  50.         retract(state(R,PS,SP,F)),
  51.         arg(6,R,H),
  52.         arg(7,R,L),
  53.         get_mem(H,L,Data),
  54.         argrep(R,D,Data,NewR),
  55.         asserta(state(NewR,PC,SP,F)).
  56.  
  57. move(S,mem) :-
  58.         state(R,PS,SP,F),
  59.         arg(6,R,H),
  60.         arg(7,R,L),
  61.         arg(S,R,Data),
  62.         put_mem(H,L,Data).
  63.  
  64. move( S,D ) :-
  65.         retract(state(R,P,SP,F)),
  66.         arg(S,R,S1),
  67.         argrep(R,D,S1,NewR),
  68.         asserta(state(NewR,P,SP,F)).
  69.  
  70. reg_ptr(6,mem).
  71. reg_ptr(A,B) :- B is (A + 2) mod 8.
  72.  
  73. op(0).                  /* NOP */
  74.  
  75. op(1) :-                /* LXI BC */
  76.         retract(state(regs(A,_,_,D,E,H,L),PC,SP,Flags)),
  77.         get_mem(PC,C),  Hi is PC + 1,
  78.         get_mem(Hi,B),
  79.         NewPC is PC + 2,
  80.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  81.  
  82. op(2) :-                /* STAX B */
  83.         state(regs(A,B,C,_,_,_,_),_,_,_),
  84.         put_mem(B,C,A).
  85.  
  86. op(3)  :-               /* INX B */
  87.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  88.         BC is 256 * B + C + 1,
  89.         decompose(BC,NewB,NewC),
  90.         asserta(state(regs(A,NewB,NewC,D,E,H,L),PC,SP,Flags)).
  91.  
  92. op(4) :-       reg_math(inc,b),!.         /* INR B */
  93.  
  94. op(5) :-       reg_math(dec,b),!.         /* DCR B */
  95.  
  96. op(6)  :-               /* MVI B, data */
  97.         retract(state(regs(A,_,C,D,E,H,L),PC,SP,Flags)),
  98.         get_mem(PC,B),
  99.         NewPC is PC + 1,
  100.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  101.  
  102. op(7) :-                /* RLC */
  103.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,_,AC))),
  104.         CY is A mod 128,
  105.         A1 is (2 * A + CY) mod 256,
  106.         asserta(state(regs(A1,B,C,D,E,H,L),PC,SP,flags(Z,S,P,CY,AC))).
  107.  
  108. op(9) :-                /* DAD B (CY only)*/
  109.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,_,AC))),
  110.         NewL is L + C,
  111.         Carry is NewL // 256,
  112.         NewH is H + B + Carry,
  113.         CY is NewH // 256,
  114.         FL is NewL /\ 255,
  115.         FH is NewH /\ 255,
  116.         asserta(state(regs(A,B,C,D,E,FH,FL),PC,SP,flags(Z,S,P,CY,AC))).
  117.  
  118. op(10) :-                /* LDAX B */
  119.         retract(state(regs(_,B,C,D,E,H,L),PC,SP,Flags)),
  120.         get_mem(B,C,A),
  121.         asserta(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)).
  122.  
  123. op(11) :-                /* DCX B */
  124.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  125.         BC is 256 * B + C - 1,
  126.         decompose(BC,B1,C1),
  127.         asserta(state(regs(A,B1,C1,D,E,H,L),PC,SP,Flags)).
  128.  
  129.  
  130. op(12) :-      reg_math(inc,c),!.         /* INR C */
  131.  
  132. op(13) :-      reg_math(dec,c),!.         /* DCR C */
  133.  
  134. op(14)  :-              /* MVI C, data */
  135.         retract(state(regs(A,B,_,D,E,H,L),PC,SP,Flags)),
  136.         get_mem(PC,C),
  137.         NewPC is PC + 1,
  138.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  139.  
  140. op(15) :-               /* RRC */
  141.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,_,AC))),
  142.         CY is A mod 2,
  143.         I1 is CY * 128,
  144.         A1 is A // 2 + I1,
  145.         asserta(state(regs(A1,B,C,D,E,H,L),PC,SP,flags(Z,S,P,CY,AC))).
  146.  
  147. op(17) :-               /* LXI DE */
  148.         retract(state(regs(A,B,C,_,_,H,L),PC,SP,Flags)),
  149.         memory(PC,E),
  150.         Hi is PC + 1,
  151.         memory(Hi,D),
  152.         NewPC is PC + 2,
  153.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  154.  
  155. op(18) :-               /* STAX D */
  156.         state(regs(A,_,_,D,E,_,_),_,_,_),
  157.         put_mem(D,E,A).
  158.  
  159. op(19)  :-              /* INX D */
  160.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  161.         DE is 256 * D + E + 1,
  162.         D1 is DE // 256,
  163.         E1 is DE mod 256,
  164.         asserta(state(regs(A,B,C,D1,E1,H,L),PC,SP,Flags)).
  165.  
  166. op(20) :-      reg_math(inc,d),!.         /* INR D */
  167.  
  168. op(21) :-      reg_math(dec,d),!.         /* DCR D */
  169.  
  170. op(22)  :-              /* MVI D, data */
  171.         retract(state(regs(A,B,C,_,E,H,L),PC,SP,Flags)),
  172.         memory(PC,D),
  173.         NewPC is PC + 1,
  174.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  175.  
  176. op(23) :-               /* RAL */
  177.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,CY,AC))),
  178.         A1 is (2 * A + CY) mod 256,
  179.         NewCY is A mod 128,
  180.         asserta(state(regs(A1,B,C,D,E,H,L),PC,SP,flags(Z,S,P,NewCY,AC))).
  181.  
  182. op(25) :-                /* DAD D */
  183.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,_,AC))),
  184.         NewL is L + E,
  185.         Carry is NewL // 256,
  186.         NewH is H + D + Carry,
  187.         CY is NewH // 256,
  188.         FL is NewL /\ 255,
  189.         FH is NewH /\ 255,
  190.         asserta(state(regs(A,B,C,D,E,FH,FL),PC,SP,flags(Z,S,P,CY,AC))).
  191.  
  192. op(26) :-               /* LDAX D  */
  193.         retract(state(regs(_,B,C,D,E,H,L),PC,SP,Flags)),
  194.         get_mem(D,E,A),
  195.         asserta(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)).
  196.  
  197. op(27) :-              /* DCX D */
  198.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  199.         DE is 256 * D + E - 1,
  200.         decompose(DE,D1,E1),
  201.         asserta(state(regs(A,B,C,D1,E1,H,L),PC,SP,Flags)).
  202.  
  203.  
  204. op(28) :-      reg_math(inc,e),!.         /* INR E */
  205.  
  206. op(29) :-      reg_math(dec,e),!.         /* DCR E */
  207.  
  208. op(30)  :-              /* MVI E, data */
  209.         retract(state(regs(A,B,C,D,_,H,L),PC,SP,Flags)),
  210.         get_mem(PC,E),
  211.         NewPC is PC + 1,
  212.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  213.  
  214. op(31) :-           /* RAR */
  215.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,CY,AC))),
  216.         A1 is (A // 2) + (128 * CY),
  217.         NewCY is A mod 2,
  218.         asserta(state(regs(A1,B,C,D,E,H,L),PC,SP,flags(Z,S,P,NewCY,AC))).
  219.  
  220. op(32) :-               /* RIM (read interrupt mask) */
  221.         not_implemented.
  222.  
  223. op(33) :-               /* LXI HL */
  224.         retract(state(regs(A,B,C,D,E,_,_),PC,SP,Flags)),
  225.         get_mem(PC,L),
  226.         Hi is PC + 1,
  227.         get_mem(Hi,H),
  228.         NewPC is PC + 2,
  229.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  230.  
  231. op(34) :-               /* SHLD (store H L direct) */
  232.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  233.         get_mem(PC,Lo),        NextPC is PC + 1,
  234.         get_mem(NextPC,Hi),
  235.         put_mem(Hi,Lo,L),      NextLo is Lo + 1,
  236.         put_mem(Hi,NextLo,H),
  237.         NewPC is PC + 2,
  238.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  239.  
  240.  
  241. op(35)  :-              /* INX H */
  242.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  243.         HL is 256 * H + L + 1,
  244.         decompose(HL,H1,L1),
  245.         asserta(state(regs(A,B,C,D,E,H1,L1),PC,SP,Flags)).
  246.  
  247. op(36) :-      reg_math(inc,h),!.         /* INR H */
  248.  
  249. op(37) :-      reg_math(dec,h),!.         /* DCR H */
  250.  
  251. op(38)  :-              /* MVI H, data */
  252.         retract(state(regs(A,B,C,D,E,_,L),PC,SP,Flags)),
  253.         get_mem(PC,H),
  254.         NewPC is PC + 1,
  255.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  256.  
  257. op(39) :-               /* DAA */
  258.         state(regs(A,B,C,D,E,H,L),_,_,flags(Z,S,P,CY,AC)),
  259.         LSB is A /\ 15,
  260.         LSB > 9;
  261.         AC is 1, !, retract(state(_,PC,SP,F)),
  262.         NewA is A + 6,
  263.         asserta(state(regs(NewA,B,C,D,E,H,L),PC,SP,F)),
  264.         MSB is NewA /\ 240,
  265.         MSB > 9;
  266.         CY is 1, !, retract(_,PC,_,_),
  267.         FinalA is NewA + 6,
  268.         asserta(state(regs(FinalA,B,C,D,E,H,L),PC,SP,F)).
  269.  
  270. op(41) :-                /* DAD H */
  271.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,_,AC))),
  272.         NewL is L + L,          % sum L plus lo-order register
  273.         Carry is NewL // 256,   % Carry is one if NewL > 255
  274.         NewH is H + H + Carry,  % sum H with hi-order register
  275.         CY is NewH // 256,      % CY flag is one if NewH > 255
  276.         FL is NewL /\ 255,      % bring into byte range
  277.         FH is NewH /\ 255,      % this one too
  278.         asserta(state(regs(A,B,C,D,E,FH,FL),PC,SP,flags(Z,S,P,CY,AC))).
  279.  
  280. op(42) :-               /* LHLD (load H L direct) */
  281.         retract(state(regs(A,B,C,D,E,_,_),PC,SP,Flags)),
  282.         get_mem(PC,Lo),        NextPC is PC + 1,
  283.         get_mem(NextPC,Hi),
  284.         get_mem(Hi,Lo,L),      NextLo is Lo + 1,
  285.         get_mem(Hi,NextLo,H),
  286.         NewPC is PC + 2,
  287.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  288.  
  289. op(43) :-      /* DCX H */
  290.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  291.         HL is 256 * H + L - 1,
  292.         decompose(HL,H1,L1),
  293.         asserta(state(regs(A,B,C,D,E,H1,L1),PC,SP,Flags)).
  294.  
  295. op(44) :-      reg_math(inc,l),!.         /* INR L */
  296.  
  297. op(45) :-      reg_math(dec,l),!.         /* DCR L */
  298.  
  299. op(46)  :-              /* MVI L, data */
  300.         retract(state(regs(A,B,C,D,E,H,_),PC,SP,Flags)),
  301.         get_mem(PC,L),
  302.         NewPC is PC + 1,
  303.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  304.  
  305. op(47) :-               /* CMA (complement accumulator) */
  306.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  307.         bit_xor(A,255,NewA),
  308.         asserta(state(regs(NewA,B,C,D,E,H,L),PC,SP,Flags)).
  309.  
  310. op(48) :-               /* SIM (set interrupt mask)         */
  311.         not_implemented.
  312.  
  313. op(49) :-               /* LXI SP */
  314.         retract(state(Regs,PC,_,Flags)),
  315.         get_mem(PC,SPL),
  316.         Hi is PC + 1,
  317.         get_mem(Hi,SPH),
  318.         SP is 256 * SPH + SPL,
  319.         NewPC is PC + 2,
  320.         asserta(state(Regs,NewPC,SP,Flags)).
  321.  
  322. op(50) :-               /* STA Adr (store accumulator in address) */
  323.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  324.         get_mem(PC,Lo),        HiAdr is PC + 1,
  325.         get_mem(HiAdr, Hi),
  326.         put_mem(Hi,Lo,A),
  327.         NewPC is PC + 2,
  328.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  329.  
  330. op(51)  :-              /* INX SP */
  331.         retract(state(Regs,PC,SP,Flags)),
  332.         NewSP is SP + 1,
  333.         check_overflow(NewSP,FinalSP),
  334.         asserta(state(Regs,PC,FinalSP,Flags)).
  335.  
  336. op(52) :-           /* INR M  */
  337.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(_,_,_,CY,_))),
  338.         get_mem(H,L,Data),
  339.         NewData is Data + 1,
  340.         adjust_flags(A,NewData,FinalData,flags1(Z,S,P,_,AC)),
  341.         put_mem(H,L,FinalData),
  342.         asserta(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,CY,AC))).
  343.  
  344. op(53) :-           /* DCR M */
  345.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(_,_,_,CY,_))),
  346.         get_mem(H,L,Data),
  347.         NewData is Data - 1,
  348.         adjust_flags(A,NewData,FinalData,flags1(Z,S,P,_,AC)),
  349.         put_mem(H,L,FinalData),
  350.         asserta(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,CY,AC))).
  351.  
  352. op(54)  :-              /* MVI M, data */
  353.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  354.         get_mem(PC,Data),
  355.         put_mem(H,L,Data),
  356.         NewPC is PC + 1,
  357.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  358.  
  359. op(55) :-           /* STC (set carry) */
  360.         retract(state(Regs,PC,SP,flags(Z,S,P,_,AC))),
  361.         asserta(state(Regs,PC,SP,flags(Z,S,P,1,AC))).
  362.  
  363. op(57) :-           /* DAD SP */
  364.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,_,AC))),
  365.         decompose(SP,SPH,SPL),
  366.         NewL is L + SPL,
  367.         Carry is NewL // 256,
  368.         NewH is H + SPH + Carry,
  369.         CY is NewH // 256,
  370.         FL is NewL /\ 255,
  371.         FH is NewH /\ 255,
  372.         asserta(state(regs(A,B,C,D,E,FH,FL),PC,SP,flags(Z,S,P,CY,AC))).
  373.  
  374. op(58) :-           /* LDA Adr  */
  375.         retract(state(regs(_,B,C,D,E,H,L),PC,SP,Flags)),
  376.         get_mem(PC,Lo),
  377.         NextPC is PC + 1,
  378.         get_mem(NextPC,Hi),
  379.         get_mem(Hi,Lo,A),
  380.         NewPC is PC + 2,
  381.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  382.  
  383. op(59) :-                /* DCX SP */
  384.         retract(state(Registers,PC,SP,Flags)),
  385.         NewSP is SP - 1,
  386.         check_overflow(NewSP,FinalSP),
  387.         asserta(state(Registers,PC,FinalSP,Flags)).
  388.  
  389.  
  390. op(60) :-      reg_math(inc,a),!.         /* INR A */
  391.  
  392. op(61) :-      reg_math(dec,a),!.         /* DCR A */
  393.  
  394. op(62) :-           /* MVI A, Data */
  395.         retract(state(regs(_,B,C,D,E,H,L),PC,SP,Flags)),
  396.         get_mem(PC,A),
  397.         NewPC is PC + 1,
  398.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  399.  
  400. op(63) :-           /* CMC (complement carry) */
  401.         retract(state(Regs,PC,SP,flags(Z,S,P,CY,AC))),
  402.         bit_xor(1,CY,NewCY),
  403.         asserta(state(Regs,PC,SP,flags(Z,S,P,NewCY,AC))).
  404.  
  405. op(Code) :-    /*  MOV Destination, Source */
  406.         Code > 63, Code < 128,
  407.         B210 is Code /\ 7,          % decode which reg is in bits 0-2
  408.         B543 is (Code /\ 56) >> 3,  % do same for bits 3-5
  409.         reg_ptr(B210,S),
  410.         reg_ptr(B543,D),
  411.         move(S,D).
  412.  
  413. op(128) :-     acc_math(+,b),!.
  414.  
  415. op(129) :-     acc_math(+,c),!.
  416.  
  417. op(130) :-     acc_math(+,d),!.
  418.  
  419. op(131) :-     acc_math(+,e),!.
  420.  
  421. op(132) :-     acc_math(+,h),!.
  422.  
  423. op(133) :-     acc_math(+,l),!.
  424.  
  425. op(134) :-
  426.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  427.         get_mem(H,L,Q),
  428.         X is A + Q,
  429.         adjust_flags(A,X,Y,Flags),
  430.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,Flags)).
  431.  
  432. op(135) :-     acc_math(+,a),!.
  433.  
  434. op(136) :-     acc_math_with_carry(+,b),!.      % add B with carry
  435.  
  436. op(137) :-     acc_math_with_carry(+,c),!.
  437.  
  438. op(138) :-     acc_math_with_carry(+,d),!.
  439.  
  440. op(139) :-     acc_math_with_carry(+,e),!.
  441.  
  442. op(140) :-     acc_math_with_carry(+,h),!.
  443.  
  444. op(141) :-     acc_math_with_carry(+,l),!.
  445.  
  446. op(142) :-
  447.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  448.         get_mem(H,L,Q),
  449.         X is A + Q,
  450.         adjust_flags(A,X,Y,Flags),
  451.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,Flags)).
  452.  
  453. op(143) :-     acc_math_with_carry(+,a),!.
  454.  
  455. op(144) :-     acc_math(-,b),!.
  456.  
  457. op(145) :-     acc_math(-,c),!.
  458.  
  459. op(146) :-     acc_math(-,d),!.
  460.  
  461. op(147) :-     acc_math(-,e),!.
  462.  
  463. op(148) :-     acc_math(-,h),!.
  464.  
  465. op(149) :-     acc_math(-,l),!.
  466.  
  467. op(150) :-
  468.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  469.         get_mem(H,L,Q),
  470.         X is A + Q,
  471.         adjust_flags(A,X,Y,Flags),
  472.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,Flags)).
  473.  
  474. op(151) :-     acc_math(-,a),!.
  475.  
  476. op(152) :-     acc_math_with_carry(-,b),!.
  477.  
  478. op(153) :-     acc_math_with_carry(-,c),!.
  479.  
  480. op(154) :-     acc_math_with_carry(-,d),!.
  481.  
  482. op(155) :-     acc_math_with_carry(-,e),!.
  483.  
  484. op(156) :-     acc_math_with_carry(-,h),!.
  485.  
  486. op(157) :-     acc_math_with_carry(-,l),!.
  487.  
  488. op(158) :-
  489.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(_,_,_,CY,_))),
  490.         get_mem(H,L,Q),
  491.         X is A - Q - CY,
  492.         adjust_flags(A,X,Y,Flags),
  493.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,Flags)).
  494.  
  495. op(159) :-     acc_math_with_carry(-,a),!.
  496.  
  497. op(160) :-     acc_math(/\,b),!.
  498.  
  499. op(161) :-     acc_math(/\,c),!.
  500.  
  501. op(162) :-     acc_math(/\,d),!.
  502.  
  503. op(163) :-     acc_math(/\,e),!.
  504.  
  505. op(164) :-     acc_math(/\,h),!.
  506.  
  507. op(165) :-     acc_math(/\,l),!.
  508.  
  509. op(166) :-
  510.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  511.         get_mem(H,L,M),
  512.         X is A /\ M,
  513.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  514.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,1))).
  515.  
  516. op(167) :-          % AND A  (affects flags)
  517.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  518.         adjust_flags(A,A,Y,flags(Z,S,P,_,_)),
  519.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,1))).
  520.  
  521. op(168) :-
  522.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  523.         bit_xor(A,B,X),
  524.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  525.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  526.  
  527. op(169) :-
  528.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  529.         bit_xor(A,C,X),
  530.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  531.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  532.  
  533. op(170) :-
  534.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  535.         bit_xor(A,D,X),
  536.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  537.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  538.  
  539. op(171) :-
  540.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  541.         bit_xor(A,E,X),
  542.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  543.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  544.  
  545. op(172) :-
  546.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  547.         bit_xor(A,H,X),
  548.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  549.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  550.  
  551. op(173) :-
  552.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  553.         bit_xor(A,L,X),
  554.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  555.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  556.  
  557. op(174) :-
  558.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  559.         get_mem(H,L,M),
  560.         bit_xor(A,M,X),
  561.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  562.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  563.  
  564. op(175) :-
  565.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  566.         bit_xor(A,A,X),
  567.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  568.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  569.  
  570. op(176) :-     acc_math(\/,b),!.
  571.  
  572. op(177) :-     acc_math(\/,c),!.
  573.  
  574. op(178) :-     acc_math(\/,d),!.
  575.  
  576. op(179) :-     acc_math(\/,e),!.         /* ORA E */
  577.  
  578. op(180) :-     acc_math(\/,h),!.         /* ORA H */
  579.  
  580. op(181) :-     acc_math(\/,l),!.
  581.  
  582. op(182) :-
  583.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  584.         get_mem(H,L,M),
  585.         X is A \/ M,
  586.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  587.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  588.  
  589. op(183) :-
  590.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  591.         adjust_flags(A,A,Y,flags(Z,S,P,_,_)),
  592.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  593.  
  594. op(184) :-     comp_regs(b),!.     /* CMP B */
  595.  
  596. op(185) :-     comp_regs(c),!.     /* CMP C */
  597.  
  598. op(186) :-     comp_regs(d),!.     /* CMP D */
  599.  
  600. op(187) :-     comp_regs(e),!.     /* CMP E */
  601.  
  602. op(188) :-     comp_regs(h),!.     /* CMP H */
  603.  
  604. op(189) :-     comp_regs(l),!.     /* CMP L */
  605.  
  606. op(190) :-          /* CMP M */
  607.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  608.         get_mem(H,L,Q),
  609.         X is A - Q,
  610.         adjust_flags(A,X,_,Flags),
  611.         asserta(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)).
  612.  
  613. op(191) :-              /* CMP A */
  614.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  615.         adjust_flags(A,0,_,Flags),
  616.         asserta(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)).
  617.  
  618. op(192) :-      /* RNZ */
  619.         (not zero_flag_is_set, return); true.
  620.  
  621.  
  622. op(193) :-        /* POP B */
  623.        retract(state(regs(A,_,_,D,E,H,L),PC,SP,Flags)),
  624.        get_mem(SP,C),
  625.        Hi is SP + 1,
  626.        get_mem(Hi,B),
  627.        NewSP is SP + 2,
  628.        asserta(state(regs(A,B,C,D,E,H,L),PC,NewSP,Flags)).
  629.  
  630. op(194) :-      /* JNZ */
  631.         (not zero_flag_is_set, jump); carry_on.
  632.  
  633. op(195) :-      /* JMP */
  634.         jump.
  635.  
  636. op(196) :-      /* CNZ */
  637.         (not zero_flag_is_set, call); carry_on.
  638.  
  639. op(197) :-          /* PUSH B */
  640.        retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  641.        Hi is SP - 1,
  642.        put_mem(Hi,B),
  643.        Lo is SP - 2,
  644.        put_mem(Lo,C),
  645.        NewSP is SP - 2,
  646.        asserta(state(regs(A,B,C,D,E,H,L),PC,NewSP,Flags)).
  647.  
  648. op(198) :-          /* ADI D8 */
  649.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  650.         get_mem(PC,Q),
  651.         X is A + Q,
  652.         adjust_flags(A,X,Y,Flags),
  653.         NewPC is PC + 1,
  654.         asserta(state(regs(Y,B,C,D,E,H,L),NewPC,SP,Flags)).
  655.  
  656. op(199) :-        /* RST 0 */
  657.       reset(0).
  658.  
  659. op(200) :-      /* RZ  */
  660.         (zero_flag_is_set, return); true.
  661.  
  662. op(201) :-      /* RET */
  663.         return.
  664.  
  665. op(202) :-      /* JZ */
  666.         (zero_flag_is_set, jump); carry_on.
  667.  
  668. op(204) :-      /* CZ */
  669.         (zero_flag_is_set, call); carry_on.
  670.  
  671. op(205) :-      /* CALL */
  672.         call.
  673.  
  674. op(206) :-          /* ACI D8 */
  675.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(_,_,_,CY,_))),
  676.         get_mem(PC,Q),
  677.         X is A + Q + CY,
  678.         adjust_flags(A,X,Y,Flags),
  679.         NewPC is PC + 1,
  680.         asserta(state(regs(Y,B,C,D,E,H,L),NewPC,SP,Flags)).
  681.  
  682. op(207) :-        /* RST 1 */
  683.       reset(1).
  684.  
  685. op(208) :-      /* RNC */
  686.         (not carry_flag_is_set, return); true.
  687.  
  688. op(209) :-        /* POP D */
  689.        retract(state(regs(A,B,C_,_,H,L),PC,SP,Flags)),
  690.        get_mem(SP,E),
  691.        Hi is SP + 1,
  692.        get_mem(Hi,D),
  693.        NewSP is SP + 2,
  694.        asserta(state(regs(A,B,C,D,E,H,L),PC,NewSP,Flags)).
  695.  
  696.  
  697. op(210) :-      /* JNC */
  698.         (not carry_flag_is_set, jump); carry_on.
  699.  
  700. op(211) :-         /* OUT */
  701.         not_implemented.
  702.  
  703.  
  704. op(212) :-      /* CNC */
  705.         (not carry_flag_is_set, call); carry_on.
  706.  
  707. op(213) :-          /* PUSH D */
  708.        retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  709.        Hi is SP - 1,
  710.        put_mem(Hi,D),
  711.        Lo is SP - 2,
  712.        put_mem(Lo,E),
  713.        NewSP is SP - 2,
  714.        asserta(state(regs(A,B,C,D,E,H,L),PC,NewSP,Flags)).
  715.  
  716. op(214) :-          /* SUI D8 */
  717.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  718.         get_mem(PC,Q),
  719.         X is A - Q,
  720.         adjust_flags(A,X,Y,Flags),
  721.         NewPC is PC + 1,
  722.         asserta(state(regs(Y,B,C,D,E,H,L),NewPC,SP,Flags)).
  723.  
  724. op(215) :-        /* RST 2 */
  725.       reset(2).
  726.  
  727. op(216) :-      /* RC */
  728.         (carry_flag_is_set, return); true.
  729.  
  730. op(218) :-      /* JC */
  731.         (carry_flag_is_set, jump); carry_on.
  732.  
  733. op(219) :-       /* IN */
  734.         not_implemented.
  735.  
  736. op(220) :-      /* CC */
  737.         (carry_flag_is_set, call); carry_on.
  738.  
  739. op(222) :-          /* SBI */
  740.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(_,_,_,CY,_))),
  741.         get_mem(PC,Q),
  742.         X is A - Q - CY,
  743.         adjust_flags(A,X,Y,Flags),
  744.         NewPC is PC + 1,
  745.         asserta(state(regs(Y,B,C,D,E,H,L),NewPC,SP,Flags)).
  746.  
  747. op(223) :-        /* RST 3 */
  748.       reset(3).
  749.  
  750. op(224) :-      /* RPO odd parity; flag is 0 */
  751.         (not parity_flag_is_set, return); true.
  752.  
  753. op(225) :-        /* POP H */
  754.        retract(state(regs(A,B,C,D,E,_,_),PC,SP,Flags)),
  755.        get_mem(SP,L),
  756.        Hi is SP + 1,
  757.        get_mem(Hi,H),
  758.        NewSP is SP + 2,
  759.        asserta(state(regs(A,B,C,D,E,H,L),PC,NewSP,Flags)).
  760.  
  761. op(226) :-      /* JPO odd parity; flag is 0 */
  762.         (not parity_flag_is_set, jump); carry_on.
  763.  
  764. op(227) :-               /* XTHL */
  765.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  766.         get_mem(SP,NewH),
  767.         put_mem(SP,H),
  768.         SP1 is SP + 1,
  769.         get_mem(SP1,NewL),
  770.         put_mem(SP1,L),
  771.         asserta(state(regs(A,B,C,D,E,NewH,NewL),PC,SP,Flags)).
  772.  
  773. op(228) :-      /* CPO odd parity; flag is 0 */
  774.         (not parity_flag_is_set, call); carry_on.
  775.  
  776. op(229) :-          /* PUSH H */
  777.        retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  778.        Hi is SP - 1,
  779.        put_mem(Hi,H),
  780.        Lo is SP - 2,
  781.        put_mem(Lo,L),
  782.        NewSP is SP - 2,
  783.        asserta(state(regs(A,B,C,D,E,H,L),PC,NewSP,Flags)).
  784.  
  785. op(230) :-          /* ANI D8 */
  786.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  787.         get_mem(PC,M),
  788.         X is A /\ M,
  789.         adjust_flags(A,X,Y,Flags),
  790.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,Flags)).
  791.  
  792. op(231) :-        /* RST 4 */
  793.       reset(4).
  794.  
  795. op(232) :-      /* RPE odd parity; flag is 1 */
  796.         (parity_flag_is_set, return); true.
  797.  
  798. op(233) :-          /* PCHL */
  799.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  800.         decompose(PC,PCH,PCL),     % (i,o,o)
  801.         decompose(NewPC,H,L),      % (o,i,i)
  802.         asserta(state(regs(A,B,C,D,E,PCH,PCL),NewPC,SP,Flags)).
  803.  
  804. op(234) :-      /* JPE odd parity; flag is 1 */
  805.         (parity_flag_is_set, jump); carry_on.
  806.  
  807. op(235) :-          /* XCHG */
  808.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)),
  809.         asserta(state(regs(A,B,C,H,L,D,E),PC,SP,Flags)).
  810.  
  811. op(236) :-      /* CPE odd parity; flag is 1 */
  812.         (parity_flag_is_set, call); carry_on.
  813.  
  814. op(238) :-          /* XRI D8 */
  815.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  816.         get_mem(PC,M),
  817.         bit_xor(A,M,X),
  818.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  819.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  820.  
  821. op(239) :-        /* RST 5 */
  822.       reset(5).
  823.  
  824. op(240) :-      /* RP  sign flag is 0 */
  825.         (not sign_flag_is_set, return); true.
  826.  
  827. op(241) :-        /* POP PSW */
  828.        retract(state(regs(_,B,C,D,E,H,L),PC,SP,_)),
  829.        get_mem(SP,Flags),
  830.        Hi is SP + 1,
  831.        get_mem(Hi,A),
  832.        NewSP is SP + 2,
  833.        S is (Flags /\ 128) / 128,
  834.        Z is (Flags /\  64) / 64,
  835.        AC is (Flags /\ 16) / 16,
  836.        P is (Flags /\ 4) / 4,
  837.        CY is Flags /\ 1,
  838.        asserta(state(regs(A,B,C,D,E,H,L),PC,NewSP,flags(Z,S,P,CY,AC))).
  839.  
  840. op(242) :-      /* JP  sign flag is 0 */
  841.         (not sign_flag_is_set, jump); carry_on.
  842.  
  843. op(243) :-          /* DI */
  844.         not_implemented.
  845.  
  846. op(244) :-      /* CP  sign flag is 0 */
  847.         (not sign_flag_is_set, call); carry_on.
  848.  
  849. op(245) :-          /* PUSH PSW */
  850.        retract(state(regs(A,B,C,D,E,H,L),PC,SP,flags(Z,S,P,CY,AC))),
  851.        Hi is SP - 1,
  852.        put_mem(Hi,A),
  853.        Lo is SP - 2,
  854.        Flags is CY * 1 + P * 4 + AC * 16 + Z * 64 + S * 128,
  855.        put_mem(Lo,Flags),
  856.        NewSP is SP - 2,
  857.        asserta(state(regs(A,B,C,D,E,H,L),PC,NewSP,flags(Z,S,P,CY,AC))).
  858.  
  859. op(246) :-          /* ORI D8 */
  860.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  861.         get_mem(PC,M),
  862.         X is A \/ M,
  863.         adjust_flags(A,X,Y,flags(Z,S,P,_,_)),
  864.         asserta(state(regs(Y,B,C,D,E,H,L),PC,SP,flags(Z,S,P,0,0))).
  865.  
  866. op(247) :-        /* RST 6 */
  867.       reset(6).
  868.  
  869. op(248) :-      /* RM  sign flag is 1 */
  870.         (sign_flag_is_set, return); true.
  871.  
  872. op(249) :-          /* SPHL */
  873.         retract(state(regs(A,B,C,D,E,H,L),PC,_,Flags)),
  874.         decompose(SP,H,L),      % (o,i,i)
  875.         asserta(state(regs(A,B,C,D,E,H,L),PC,SP,Flags)).
  876.  
  877. op(250) :-      /* JM  sign flag is 1 */
  878.         (sign_flag_is_set, jump); carry_on.
  879.  
  880. op(251) :-          /* EI */
  881.         not_implemented.
  882.  
  883. op(252) :-      /* CM  sign flag is 1 */
  884.         (sign_flag_is_set, call); carry_on.
  885.  
  886. op(254) :-          /* CPI D8 */
  887.         retract(state(regs(A,B,C,D,E,H,L),PC,SP,_)),
  888.         get_mem(PC,Q),
  889.         X is A - Q,
  890.         adjust_flags(A,X,Y,Flags),
  891.         NewPC is PC + 1,
  892.         asserta(state(regs(A,B,C,D,E,H,L),NewPC,SP,Flags)).
  893.  
  894. op(255) :-        /* RST 7 */
  895.       reset(7).
  896.  
  897. op(_) :- write('undefined opcode'), nl.
  898.  
  899. %
  900. % end: OPS8085.ARI
  901.